package com.kk.xhr.model.service.impl;

import com.kk.xhr.common.pojo.BinaryEnum;
import com.kk.xhr.model.assembler.TransferStructKit;
import com.kk.xhr.model.dao.RewardDynamicSqlSupport;
import com.kk.xhr.model.dao.TransferDynamicSqlSupport;
import com.kk.xhr.model.dao.TransferMapper;
import com.kk.xhr.model.dto.PageDto;
import com.kk.xhr.model.dto.TransferDTO;
import com.kk.xhr.model.dto.TransferQueryRequestDTO;
import com.kk.xhr.model.entity.Transfer;
import com.kk.xhr.model.service.ITransferService;
import lombok.RequiredArgsConstructor;
import org.mybatis.dynamic.sql.where.AbstractWhereDSL;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualToWhenPresent;
import static org.mybatis.dynamic.sql.SqlBuilder.isGreaterThanOrEqualToWhenPresent;
import static org.mybatis.dynamic.sql.SqlBuilder.isLessThanOrEqualToWhenPresent;

/**
 * 调岗服务接口实现
 *
 * @author kkmystery
 * @version 1.0 2021/3/6
 * @since 1.0.0
 */
@Repository
@RequiredArgsConstructor
public class TransferServiceImpl implements ITransferService {
    private final TransferMapper transferMapper;
    private final TransferStructKit instance = TransferStructKit.INSTANCE;

    /**
     * {@inheritDoc}
     */
    @Override
    public Optional<TransferDTO> queryById(Long id) {
        return transferMapper.selectOne(dsl -> dsl
            .where(RewardDynamicSqlSupport.id, isEqualTo(id)))
            .map(instance::toDto);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public PageDto<TransferDTO> queryPage(TransferQueryRequestDTO dto) {
        long count = transferMapper.count(dsl -> applyQueryArgs(dsl.where(), dto));
        if (0 == count) {
            return PageDto.empty();
        }
        return new PageDto<>(count, transferMapper.select(dsl ->
            applyQueryArgs(dsl.where(), dto)
                .orderBy(TransferDynamicSqlSupport.id.descending())
                .limit(dto.getLimit())
                .offset(dto.getOffset()))
            .stream()
            .map(instance::toDto)
            .collect(Collectors.toList()));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<TransferDTO> queryByUserId(Long userId) {
        return transferMapper.select(dsl -> dsl
            .where(RewardDynamicSqlSupport.userId, isEqualTo(userId))
            .and(RewardDynamicSqlSupport.status, isEqualTo(BinaryEnum.TRUE.getValue())))
            .stream()
            .map(instance::toDto)
            .collect(Collectors.toList());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean add(TransferDTO dto) {
        return 1 == transferMapper.insertSelective(instance.toEntity(dto));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean modify(TransferDTO dto) {
        if (null == dto.getId()) {
            return false;
        }
        return 1 == transferMapper.updateByPrimaryKeySelective(instance.toEntity(dto));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean modifyStatus(Long id, BinaryEnum status) {
        if (null == status) {
            return false;
        }
        return 1 == transferMapper.updateByPrimaryKeySelective(new Transfer().withId(id).withStatus(status.getValue()));
    }

    private <T extends AbstractWhereDSL> T applyQueryArgs(T where, TransferQueryRequestDTO dto) {
        where.and(TransferDynamicSqlSupport.userId, isEqualToWhenPresent(dto.getUserId()))
            .and(TransferDynamicSqlSupport.removeDate, isGreaterThanOrEqualToWhenPresent(dto.getBegin()))
            .and(TransferDynamicSqlSupport.removeDate, isLessThanOrEqualToWhenPresent(dto.getEnd()));
        return where;
    }
}
